package com.example.demo.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * 常用工具类
 */
public class CommonUtil {

    /**
     * 获取常用参数变量值
     *
     * @param param
     * @return
     */
    public static Object getCommonParamValue(String param) {
        if (null == param) {
            return null;
        }
        DateTime dateTime = new DateTime();
        String paramValue = "";
        switch (param) {
            case "${current_day}":
                paramValue = dateTime.toDateStr();
                break;
            case "${current_year}":
                paramValue = String.valueOf(dateTime.year());
                break;
            case "${now}":
                paramValue = dateTime.toString();
                break;
            case "${beginOfMonth}":
                paramValue = DateUtil.beginOfMonth(dateTime).toDateStr();
                break;
            case "${beginOfWeek}":
                paramValue = DateUtil.beginOfWeek(dateTime, true).toDateStr();
                break;
            case "${current_month}":
                paramValue = dateTime.toString("yyyy-MM");
                break;
            case "${beginOfYear}":
                paramValue = DateUtil.beginOfYear(dateTime).toDateStr();
                break;
            case "${yesterday}":
                paramValue = DateUtil.yesterday().toDateStr();
                break;
            case "${current_day_ms}":
                paramValue = dateTime.toString("yyyy-MM-dd HH:mm:ss:sss");
                break;
            case "${timestamp}":
                paramValue = String.valueOf(dateTime.getTime());
                break;
            case "${uuid}":
                paramValue = UUID.randomUUID().toString();
                break;
            case "${UUID}":
                paramValue = UUID.randomUUID().toString();
                break;
            case "${beginTimeOfToday}":
                paramValue = beginOrEndTimeOfTimeUnit(1, true);
                break;
            case "${endTimeOfToday}":
                paramValue = beginOrEndTimeOfTimeUnit(1, false);
                break;
            case "${beginTimeOfMonth}":
                paramValue = beginOrEndTimeOfTimeUnit(2, true);
                break;
            case "${endTimeOfMonth}":
                paramValue = beginOrEndTimeOfTimeUnit(2, false);
                break;
            case "${beginTimeOfYear}":
                paramValue = beginOrEndTimeOfTimeUnit(3, true);
                break;
            case "${endTimeOfYear}":
                paramValue = beginOrEndTimeOfTimeUnit(3, false);
                break;
            default:
                paramValue = param;
        }
        return paramValue;
    }

    /**
     * 获取当前时间某时间单位下的开始或结束时间
     *
     * @param timeUnitType 时间单位（日、月、年）：1-日；2-月；3-年
     * @param isBeginTime  是否为开始时间
     * @return
     */
    public static String beginOrEndTimeOfTimeUnit(int timeUnitType, boolean isBeginTime) {
        LocalDateTime now = LocalDateTime.now();
        long timestampValue;
        switch (timeUnitType) {
            case 1:
                timestampValue = isBeginTime ? beginTimeOfDay(now) : endTimeOfDay(now);
                break;
            case 2:
                timestampValue = isBeginTime ? beginTimeOfMonth(now) : endTimeOfMonth(now);
                break;
            case 3:
                timestampValue = isBeginTime ? beginTimeOfYear(now) : endTimeOfYear(now);
                break;
            default:
                timestampValue = localDateTimeToTimestamp(now);
        }
        return Long.toString(timestampValue);
    }

    public static long beginTimeOfDay(LocalDateTime localDateTime) {
        return localDateTimeToTimestamp(beginOfDay(localDateTime));
    }

    public static long endTimeOfDay(LocalDateTime localDateTime) {
        return localDateTimeToTimestamp(endOfDay(localDateTime));
    }

    public static long beginTimeOfMonth(LocalDateTime localDateTime) {
        return localDateTimeToTimestamp(beginOfMonth(localDateTime));
    }

    public static long endTimeOfMonth(LocalDateTime localDateTime) {
        return localDateTimeToTimestamp(endOfMonth(localDateTime));
    }

    public static long beginTimeOfYear(LocalDateTime localDateTime) {
        return localDateTimeToTimestamp(beginOfYear(localDateTime));
    }

    public static long endTimeOfYear(LocalDateTime localDateTime) {
        return localDateTimeToTimestamp(endOfYear(localDateTime));
    }

    public static long localDateTimeToTimestamp(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    public static LocalDateTime beginOfDay(LocalDateTime localDateTime) {
        return localDateTime.with(LocalTime.MIN);
    }

    public static LocalDateTime endOfDay(LocalDateTime localDateTime) {
        return localDateTime.with(LocalTime.MAX);
    }

    public static LocalDateTime beginOfMonth(LocalDateTime localDateTime) {
        return localDateTime.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
    }

    public static LocalDateTime endOfMonth(LocalDateTime localDateTime) {
        return localDateTime.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
    }

    public static LocalDateTime beginOfYear(LocalDateTime localDateTime) {
        return localDateTime.with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
    }

    public static LocalDateTime endOfYear(LocalDateTime localDateTime) {
        return localDateTime.with(TemporalAdjusters.lastDayOfYear()).with(LocalTime.MAX);
    }
}
